/*
 *  Uzebox quick and dirty tutorial
 *  Copyright (C) 2008  Alec Bourque
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/


//Exclamations show problem areas !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

#include <stdbool.h>
#include <avr/io.h>
#include <stdlib.h>
#include <avr/pgmspace.h>
#include <uzebox.h>

//#include "data/fonts.pic.inc"
//#include "data/tiles.inc"
#include "urbanmess.inc"
#include "sprites.inc"

#define STANDING 0
#define WALKING 1
#define QUICK_PUNCH 2
#define MEDIUM_PUNCH 3
#define STRONG_PUNCH 4
#define KICK 5
#define GAURD 6
#define GET_HIT 7
#define FALL 8
#define LAY_DOWN 9
#define GET_UP 10
#define RUNNING 11




typedef struct{
short x;
short y;
}point;

typedef struct{
short x;
short y;
short z;
}point3d;

typedef struct{
short x;
short y;
short w;
short h;
}box;



typedef struct{
char *map;  //pointer to tile map
short delay;// amount of time before frame switch
short flip; // next frame (incase we can do more than 2)
short attack;//is this an attack frame?(should this frame use an attack collision box)
}frame_index;

typedef struct{
frame_index frame[2]; //frame array
short current_frame;  // what frame is on the screen
short final_frame;    // what's the final frame of this animation(in case we get more than 2)
}animation_index;


typedef struct{
point3d origin;	    //where this character is.
point3d location;	    //where to draw the character on the screen
point intent;	    // the direction the character "intends" to go
point3d velocity;     // translation/displacement vector
short speed;        // the speed the character intentionally will move
short balance;      // balance when this is down you fall
short gaurd;	    // gaurd ability
short life;         // the amount of life the character has
short action;       // the current action the character is in.  eg. WALKING/PUNCHING/GETTING_HIT
short shake;	    // how long to make the character shake
//short jump;
short previous_action; //previous action
short facing;	    // the direction the character is facing.
short counter;	    // animation counter
//int lock_action;    // all the actions where the character can't move.
short locked;	    //current action is locked
short reset;	    //set when the animation resets.  used to check for unlock.
short flipped;
animation_index animation[11];//<=----the array of animations
short sprite_index;  //sprite index to be passed to MapSprite2()
short list_index;     // this characters number in the character list
short ai;	     // is this an ai character?
short target;        // this ai character's target.
}character;

typedef struct{
short number_of_characters;
short index;
short collision_index;
character *Character[3];
}character_list;

void init_blueninja(character *Character)
{
Character->location.y=0;
Character->location.x=0;

Character->intent.y=0;
Character->intent.x=0;

Character->velocity.y=0;
Character->velocity.x=0;

Character->balance=20;

Character->action=STANDING;

Character->facing = 1;

Character->flipped=0;

Character->speed=0;

Character->life=100;

//Character->lock_action = QUICK_PUNCH | MEDIUM_PUNCH | STRONG_PUNCH | KICK | GET_HIT | FALL | LAY_DOWN | GET_UP;

// animations

//Standing animaiton /////////////////////////////////
//frame setup:

*Character->animation[STANDING].frame[0].map=bluestand;
Character->animation[WALKING].frame[0].attack=0;
Character->animation[MEDIUM_PUNCH].frame[0].flip=0;

*(Character->animation[STANDING].frame[1].map=bluestand);
Character->animation[WALKING].frame[1].attack=0;
Character->animation[MEDIUM_PUNCH].frame[1].flip=0;

//animation setup:
Character->animation[STANDING].current_frame=0;
Character->animation[STANDING].final_frame=0;



//Walking animaiton
//frame setup;
//frame 0
*(Character->animation[WALKING].frame[0].map=bluewalk);
Character->animation[WALKING].frame[0].delay=4;
Character->animation[WALKING].frame[0].attack=0;
Character->animation[WALKING].frame[0].flip=0;
//frame 2
*(Character->animation[WALKING].frame[1].map=bluestand);
Character->animation[WALKING].frame[1].delay=4;
Character->animation[WALKING].frame[1].attack=0;
Character->animation[WALKING].frame[1].flip=0;
//animation setup:

Character->animation[WALKING].current_frame=0;
Character->animation[WALKING].final_frame=1;


//Running animaiton
//frame setup;
//frame 0
*Character->animation[RUNNING].frame[0].map=bluewalk;
Character->animation[RUNNING].frame[0].delay=2;
Character->animation[RUNNING].frame[0].attack=0;
Character->animation[RUNNING].frame[0].flip=0;
//frame 2
*Character->animation[RUNNING].frame[1].map=bluestand;
Character->animation[RUNNING].frame[1].delay=2;
Character->animation[RUNNING].frame[1].attack=0;
Character->animation[RUNNING].frame[1].flip=0;
//animation setup:

Character->animation[RUNNING].current_frame=0;
Character->animation[RUNNING].final_frame=1;

//Punching animaiton
//frame setup;
//frame 0
*(Character->animation[QUICK_PUNCH].frame[0].map=bluegaurd);
Character->animation[QUICK_PUNCH].frame[0].delay=2;
Character->animation[QUICK_PUNCH].frame[0].attack=0;
Character->animation[QUICK_PUNCH].frame[0].flip=0;
//frame 2
*(Character->animation[QUICK_PUNCH].frame[1].map=bluepunch);
Character->animation[QUICK_PUNCH].frame[1].delay=2;
Character->animation[QUICK_PUNCH].frame[1].attack=5;//<-- hit for 4 hp of damage.
Character->animation[QUICK_PUNCH].frame[1].flip=0;
//animation setup:

Character->animation[QUICK_PUNCH].current_frame=0;
Character->animation[QUICK_PUNCH].final_frame=1;

//Medium Punching animaiton
//frame setup;
//frame 0
*(Character->animation[MEDIUM_PUNCH].frame[0].map=bluehit);
Character->animation[MEDIUM_PUNCH].frame[0].delay=2;
Character->animation[MEDIUM_PUNCH].frame[0].attack=0;
Character->animation[MEDIUM_PUNCH].frame[0].flip=1;
//frame 2
*(Character->animation[MEDIUM_PUNCH].frame[1].map=bluepunch);
Character->animation[MEDIUM_PUNCH].frame[1].delay=5;
Character->animation[MEDIUM_PUNCH].frame[1].attack=10;//<-- hit for 4 hp of damage.
Character->animation[MEDIUM_PUNCH].frame[1].flip=0;
//animation setup:

Character->animation[MEDIUM_PUNCH].current_frame=0;
Character->animation[MEDIUM_PUNCH].final_frame=1;


//Kicking animaiton
//frame setup;
//frame 0
*(Character->animation[KICK].frame[0].map=bluehit);
Character->animation[KICK].frame[0].delay=2;
Character->animation[KICK].frame[0].attack=0;
Character->animation[KICK].frame[0].flip=1;
//frame 2
*(Character->animation[KICK].frame[1].map=bluekick);
Character->animation[KICK].frame[1].delay=7;
Character->animation[KICK].frame[1].attack=15;//<-- hit for 4 hp of damage.
Character->animation[KICK].frame[1].flip=0;
//animation setup:

Character->animation[KICK].current_frame=0;
Character->animation[KICK].final_frame=1;


}// END init_blueninja() //////////////////////////////////////////////////////////////////////////////////////////////////////////

void init_redninja(character *Character)
{
Character->location.y=0;
Character->location.x=0;

Character->intent.y=0;
Character->intent.x=0;

Character->velocity.y=0;
Character->velocity.x=0;

Character->balance=20;

Character->action=STANDING;

Character->speed=1;

Character->facing = 1;

Character->flipped=0;

Character->speed=0;

Character->life=100;

Character->ai = 1;

Character->target = 0;
//Character->lock_action = QUICK_PUNCH | MEDIUM_PUNCH | STRONG_PUNCH | KICK | GET_HIT | FALL | LAY_DOWN | GET_UP;

// animations

//Standing animaiton /////////////////////////////////
//frame setup:

*Character->animation[STANDING].frame[0].map=redstand;
Character->animation[STANDING].frame[0].flip=0;

*(Character->animation[STANDING].frame[1].map=redstand);
Character->animation[STANDING].frame[0].flip=0;

//animation setup:
Character->animation[STANDING].current_frame=0;
Character->animation[STANDING].final_frame=0;



//Walking animaiton
//frame setup;
//frame 0
*(Character->animation[WALKING].frame[0].map=redwalk);
Character->animation[WALKING].frame[0].delay=4;
Character->animation[WALKING].frame[0].flip=0;
//frame 2
*(Character->animation[WALKING].frame[1].map=redstand);
Character->animation[WALKING].frame[1].delay=4;
Character->animation[WALKING].frame[1].flip=0;
//animation setup:

Character->animation[WALKING].current_frame=0;
Character->animation[WALKING].final_frame=1;


//Running animaiton
//frame setup;
//frame 0
*(Character->animation[RUNNING].frame[0].map=redwalk);
Character->animation[RUNNING].frame[0].delay=2;
Character->animation[RUNNING].frame[0].attack=0;
Character->animation[RUNNING].frame[0].flip=0;
//frame 2
*(Character->animation[RUNNING].frame[1].map=redstand);
Character->animation[RUNNING].frame[1].delay=2;
Character->animation[RUNNING].frame[1].attack=0;
Character->animation[RUNNING].frame[1].flip=0;
//animation setup:

Character->animation[RUNNING].current_frame=0;
Character->animation[RUNNING].final_frame=1;

//Punching animaiton
//frame setup;
//frame 0
*(Character->animation[QUICK_PUNCH].frame[0].map=redgaurd);
Character->animation[QUICK_PUNCH].frame[0].delay=2;
Character->animation[QUICK_PUNCH].frame[0].attack=0;
Character->animation[QUICK_PUNCH].frame[0].flip=0;
//frame 2
*(Character->animation[QUICK_PUNCH].frame[1].map=redpunch);
Character->animation[QUICK_PUNCH].frame[1].delay=2;
Character->animation[QUICK_PUNCH].frame[1].attack=5;//<-- hit for 4 hp of damage.
Character->animation[QUICK_PUNCH].frame[0].flip=0;
//animation setup:

Character->animation[QUICK_PUNCH].current_frame=0;
Character->animation[QUICK_PUNCH].final_frame=1;

//Medium Punching animaiton
//frame setup;
//frame 0
*(Character->animation[MEDIUM_PUNCH].frame[0].map=redhit);
Character->animation[MEDIUM_PUNCH].frame[0].delay=2;
Character->animation[MEDIUM_PUNCH].frame[0].attack=0;
Character->animation[MEDIUM_PUNCH].frame[0].flip=1;
//frame 2
*(Character->animation[MEDIUM_PUNCH].frame[1].map=redpunch);
Character->animation[MEDIUM_PUNCH].frame[1].delay=3;
Character->animation[MEDIUM_PUNCH].frame[1].attack=10;//<-- hit for 4 hp of damage.
Character->animation[MEDIUM_PUNCH].frame[1].flip=0;
//animation setup:

Character->animation[MEDIUM_PUNCH].current_frame=0;
Character->animation[MEDIUM_PUNCH].final_frame=1;


//Kicking animaiton
//frame setup;
//frame 0
*(Character->animation[KICK].frame[0].map=redhit);

Character->animation[KICK].frame[0].delay=2;
Character->animation[KICK].frame[0].attack=0;
Character->animation[KICK].frame[0].flip=1;
//frame 2
*(Character->animation[KICK].frame[1].map=redkick);
Character->animation[KICK].frame[1].delay=4;
Character->animation[KICK].frame[1].attack=15;//<-- hit for 4 hp of damage.
Character->animation[KICK].frame[1].flip=0;
//animation setup:

Character->animation[KICK].current_frame=0;
Character->animation[KICK].final_frame=1;


//get hit animaiton
//frame setup;
//frame 0
*(Character->animation[GET_HIT].frame[0].map=redhit);

Character->animation[GET_HIT].frame[0].delay=2;
Character->animation[GET_HIT].frame[0].attack=0;
Character->animation[GET_HIT].frame[0].flip=0;
//frame 2
*(Character->animation[GET_HIT].frame[1].map=redhit);
Character->animation[GET_HIT].frame[1].delay=4;
Character->animation[GET_HIT].frame[1].attack=15;//<-- hit for 4 hp of damage.
Character->animation[GET_HIT].frame[1].flip=1;
//animation setup:

Character->animation[GET_HIT].current_frame=0;
Character->animation[GET_HIT].final_frame=1;

//fall hit animaiton
//frame setup;
//frame 0
*(Character->animation[FALL].frame[0].map=redfall);

Character->animation[FALL].frame[0].delay=1;
Character->animation[FALL].frame[0].attack=0;
Character->animation[FALL].frame[0].flip=0;
//frame 2
*(Character->animation[FALL].frame[1].map=reddown);
Character->animation[FALL].frame[1].delay=1;
Character->animation[FALL].frame[1].attack=15;//<-- hit for 4 hp of damage.
Character->animation[FALL].frame[1].flip=0;
//animation setup:

Character->animation[FALL].current_frame=0;
Character->animation[FALL].final_frame=1;



}// END init_redninja()

void animate_character(character *Character)
{	
//char temp = Character->action;

	switch(Character->action){
		case(STANDING):
			Character->locked=0;
			break;
		case(WALKING):
			Character->locked=0;
			break;
		case(QUICK_PUNCH):
			Character->locked=1;
			break;

		case(MEDIUM_PUNCH):
			Character->locked=1;
			break;

		case(STRONG_PUNCH):
			Character->locked=1;
			break;

		case(KICK):
			Character->locked=1;
			break;

		case(GAURD):
			Character->locked=1;
			break;

		case(GET_HIT):
			Character->locked=1;
			break;

		case(FALL):
			Character->locked=1;
			break;

		case(LAY_DOWN):
			Character->locked=1;
			break;
		case(GET_UP):
			Character->locked=1;
			break;

		case(RUNNING):
			Character->locked=0;
			break;
		case(777):

			break;
	}// END switch

	if (Character->action!=Character->previous_action|Character->reset){//if the character has changed his action.
							Character->previous_action=Character->action;//set previous action to the current action.
							Character->animation[Character->action].current_frame=0;//reset the current frame.
							Character->counter=0;	// clean the animation counter.
							Character->reset=0;
							}//END if the character has changed his action.

	if (//if the animation counter is >= the frame's delay time....
		Character->counter >= 
			Character->animation[
						Character->action
						].frame[
							Character->animation[Character->action].current_frame
							].delay
		){
			if (Character->animation[Character->action].current_frame>=Character->animation[Character->action].final_frame){// if it's the final frame of the animation
																	
																	if(Character->action!=FALL)Character->action=STANDING;//return the character to his standing position.
																	if(Character->action=FALL){if(Character->balance>10)Character->action=STANDING;}
																	Character->animation[Character->action].current_frame=0;//reset the current frame.
																	Character->reset++;	
																	}// END if it's the final frame of the animation	
		Character->animation[Character->action].current_frame++;//increment the current frame.
		Character->counter=0; // clear the animation counter.
																		
		}//END if the animation counter is >= the frame's delay time...
	Character->counter++;//increment the animation counter.

// handle frame flipping.  If the current frame's struce has the flip flag set flip the frame.

	Character->flipped=Character->facing;
	if(Character->animation[Character->action].frame[Character->animation[Character->action].current_frame].flip)//if the current frame is a flip frame
					{
					if(Character->flipped)Character->flipped=0;
					else if(!Character->flipped)Character->flipped=SPRITE_FLIP_X;
					}


}//END animate character /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void map_character(character *Character)// "Map" the character according to his current animation and direction he's facing.
{
		/*Character->flipped=Character->facing;
		if(Character->animation[Character->action].frame[Character->animation[Character->action].current_frame].flip)
					{
					if(Character->flipped)Character->flipped=0;
					else if(!Character->flipped)Character->flipped=SPRITE_FLIP_X;
					}*/
		MapSprite2(
			Character->sprite_index,
			Character->animation[Character->action].frame[Character->animation[Character->action].current_frame].map,			
			Character->flipped!=1?SPRITE_FLIP_X:0/*Character->facing!=1?SPRITE_FLIP_X:0*/
			);
}


void handle_character_velocity(character *Character)//handle character velocity :) ////////////////////////////////////////////////////////////////////////////////////////
{
		//if the character want's to move, move him in his direction.
		if(Character->intent.y==-1)Character->velocity.y+=Character->intent.y*Character->speed;
		if(Character->intent.y==1)Character->velocity.y+=Character->intent.y*Character->speed;
		if(Character->intent.x==-1)Character->velocity.x+=Character->intent.x*Character->speed;
		if(Character->intent.x==1)Character->velocity.x+=Character->intent.x*Character->speed;


		//set the character location for drawing him/her on the screen.
		Character->location.y+=Character->velocity.y;
		Character->location.x+=Character->velocity.x;
		Character->origin.z+=Character->velocity.z;


		//decrement the velocities so the character slows down.
		if (Character->velocity.y>0)Character->velocity.y--;
		if (Character->velocity.y<0)Character->velocity.y++;
		if (Character->velocity.x>0)Character->velocity.x--;
		if (Character->velocity.x<0)Character->velocity.x++;	
		if (Character->velocity.z>0)Character->velocity.z--;
		if (Character->velocity.z<0)Character->velocity.z++;


		if (Character->origin.z>0){Character->origin.z-=5;}

		//keep the character on the screen
		if (Character->location.y<25){Character->location.y=25;Character->velocity.y=-Character->velocity.y;}
		if (Character->location.y>112){Character->location.y=112;Character->velocity.y=-Character->velocity.y;}
		if (Character->location.x<0){Character->location.x=0;Character->velocity.x=-Character->velocity.x;}		
		if (Character->location.x>227){Character->location.x=227;Character->velocity.x=-Character->velocity.x;}	
		if (Character->origin.z<0)Character->origin.z=0;
	
		//reset the intent variable so the above multiplies don't add up.
		Character->intent.y=0;
		Character->intent.x=0;
}

void handle_ai(character_list *Character_List)/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
{
for (Character_List->index=0;Character_List->index < Character_List->number_of_characters; Character_List->index++){
	if (Character_List->Character[Character_List->index]->ai==1){
								Character_List->Character[Character_List->index]->velocity.x=1;//test
								 if(
					Character_List->Character[
								Character_List->Character[
											Character_List->index
											]->target
								]->location.x < Character_List->Character[Character_List->index]->location.x){//still in the if
																		Character_List->Character[Character_List->index]->location.x = -1;//Character_List->Character[Character_List->index]
																	}//END if
								}//end if ai
	}//END for
}// END handle_ai() /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void handle_collisions(character_list *Character_List)
{
	for (Character_List->index=0;Character_List->index < Character_List->number_of_characters; Character_List->index++){// now it get's insane.
		if(Character_List->Character[//<-- the killer if statement
						Character_List->index
					]->animation[//<----need to get whether this animation's frame is an attack frame!
							Character_List->Character[//But first i need to get this characters action.
											Character_List->index
										]->action
						].frame[//phew... now on to get this characters current frame.
							Character_List->Character[//my long list of character
										Character_List->index//<--the character i need the frame from
										]->animation[// the animation struct is hungry again and i need to send it the character's current action
												Character_List->Character[Character_List->index]->action // nice! now... where was i :)
											].current_frame
							].attack //...is an attack frame
										)

{// collision stuffs goes here :)
for (Character_List->collision_index=0;Character_List->collision_index < Character_List->number_of_characters; Character_List->collision_index++){// now it get's insane.
if(Character_List->index!=Character_List->collision_index){//if he's not gonna punch himself

//now for the if facing

if(Character_List->Character[Character_List->index]->facing){
	if(	(
		Character_List->Character[Character_List->index]->location.x > (Character_List->Character[Character_List->collision_index]->location.x-16)
		&&
		(Character_List->Character[Character_List->index]->location.x < Character_List->Character[Character_List->collision_index]->location.x+8)
		)&&(
		Character_List->Character[Character_List->index]->location.y > (Character_List->Character[Character_List->collision_index]->location.y-12)
		&&
		(Character_List->Character[Character_List->index]->location.y < Character_List->Character[Character_List->collision_index]->location.y+12)
		)&&(
		Character_List->Character[Character_List->index]->origin.z > (Character_List->Character[Character_List->collision_index]->origin.z-12)
		&&
		(Character_List->Character[Character_List->index]->origin.z < Character_List->Character[Character_List->collision_index]->origin.z+12)
		)

	){
	Character_List->Character[Character_List->collision_index]->action=GET_HIT;
	Character_List->Character[Character_List->collision_index]->balance-=Character_List->Character[Character_List->index]->animation[Character_List->Character[Character_List->index]->action].frame[Character_List->Character[Character_List->index]->animation[Character_List->Character[Character_List->index]->action].current_frame].attack;//reduce balance
			if(Character_List->Character[Character_List->collision_index]->balance<0||Character_List->Character[Character_List->collision_index]->balance>100){// if character is off balance
												Character_List->Character[Character_List->collision_index]->action=FALL;
												//Character_List->Character[Character_List->collision_index]->velocity.x+=3;//Character_List->Character[Character_List->index]->animation[Character_List->Character[Character_List->index]->action].frame[Character_List->Character[Character_List->index]->animation[Character_List->Character[Character_List->index]->action].current_frame].attack;
												//Character_List->Character[Character_List->collision_index]->velocity.z+=3;//Character_List->Character[Character_List->index]->animation[Character_List->Character[Character_List->index]->action].frame[Character_List->Character[Character_List->index]->animation[Character_List->Character[Character_List->index]->action].current_frame].attack;
												}//if off ballance

	Character_List->Character[Character_List->collision_index]->velocity.x=Character_List->Character[Character_List->index]->velocity.x*2;
	Character_List->Character[Character_List->collision_index]->velocity.y=Character_List->Character[Character_List->index]->velocity.y*2;
	Character_List->Character[Character_List->index]->life--;// test the if statement endif !!!it worked do attack collision.
	}
}//end if facing

if(!Character_List->Character[Character_List->index]->facing){//if facing left
	if(	(
		Character_List->Character[Character_List->index]->location.x > (Character_List->Character[Character_List->collision_index]->location.x-8)
		&&
		(Character_List->Character[Character_List->index]->location.x < Character_List->Character[Character_List->collision_index]->location.x+16)
		)&&(
		Character_List->Character[Character_List->index]->location.y > (Character_List->Character[Character_List->collision_index]->location.y-12)
		&&
		(Character_List->Character[Character_List->index]->location.y < Character_List->Character[Character_List->collision_index]->location.y+12)
		)&&(
		Character_List->Character[Character_List->index]->origin.z > (Character_List->Character[Character_List->collision_index]->origin.z-12)
		&&
		(Character_List->Character[Character_List->index]->origin.z < Character_List->Character[Character_List->collision_index]->origin.z+12)
		)

	){
	Character_List->Character[Character_List->collision_index]->action=GET_HIT;//oooohhhh he got slapped!
	Character_List->Character[Character_List->collision_index]->balance-=Character_List->Character[Character_List->index]->animation[Character_List->Character[Character_List->index]->action].frame[Character_List->Character[Character_List->index]->animation[Character_List->Character[Character_List->index]->action].current_frame].attack;//reduce balance
			if(Character_List->Character[Character_List->collision_index]->balance<0||Character_List->Character[Character_List->collision_index]->balance>20){// if character is off balance
												Character_List->Character[Character_List->collision_index]->action=FALL;
												//Character_List->Character[Character_List->collision_index]->velocity.x-=3;//Character_List->Character[Character_List->index]->animation[Character_List->Character[Character_List->index]->action].frame[Character_List->Character[Character_List->index]->animation[Character_List->Character[Character_List->index]->action].current_frame].attack;
												//Character_List->Character[Character_List->collision_index]->velocity.z+=13;//Character_List->Character[Character_List->index]->animation[Character_List->Character[Character_List->index]->action].frame[Character_List->Character[Character_List->index]->animation[Character_List->Character[Character_List->index]->action].current_frame].attack;
												}//if off ballance
	Character_List->Character[Character_List->collision_index]->velocity.x=Character_List->Character[Character_List->index]->velocity.x*2;
	Character_List->Character[Character_List->collision_index]->velocity.y=Character_List->Character[Character_List->index]->velocity.y*2;
	Character_List->Character[Character_List->index]->life--;// test the if statement endif !!!it worked do attack collision.
	}
}//end if !facing




	}//end if he's not gonna punch himself
}//END for collision stuffs

}//end the killer if
		}//END for the big for
}//END handle_collisions


void handle_character_states(character *Character)
{
if(Character->balance<1||Character->balance>20)Character->balance=1;
if(Character->balance<20)Character->balance++;

if(Character->shake)Character->shake--;


}


int main(){

	//Set the font and tiles to use.
	//Always invoke before any ClearVram()
	//SetFontTable(fonts);
	SetSpritesTileTable(spritemap);

	SetTileTable(uMTiles);	
	SetFontTilesIndex(0);
	//const char *mapptr = bluestand;
	//mapptr=&bluestand;

	//MapSprite(0, mapptr);
	MapSprite(4, redstand);
	MapSprite(8, redstand);
	//MapSprite(12,redstand);

	SetSpriteVisibility(true);

	
;


//Clear the screen (fills the vram with tile zero)
	ClearVram();

	
	//Draw the title
	//DrawMap2(10,1,map_title);

	//Make a brick wall
	Fill(0,1,30,4,0x40);	//DrawMap2(15,23,map_graffiti);
	//drawfloor
	Fill(0,5,30,11,0x85);
	//Draw some windows
	for (unsigned int x = 2; x < 27; x += 3){
		for (unsigned int y = 2; y < 3; y += 3){
			DrawMap2(x,y,map_window);
		}
	}
	//And the graffiti
	//draw floor
	//Fill(0,5,30,10,0x40);	//DrawMap2(15,23,map_graffiti);
	int score = 0;
	int counter =0;
	

	//Prints a string on the screen. Note that PSTR() is a macro 
	//that tells the compiler to store the string in flash.
	Print(0,0,PSTR("HEALTH!:"));Print(12,0,PSTR("BEATDOWNS!:"));
	
	character_list Character_List;
	character player1, enemy1, enemy2;
	init_blueninja(&player1);
	init_redninja(&enemy1);
	init_redninja(&enemy2);
	
	Character_List.Character[0] = &player1;
	Character_List.number_of_characters++;
	player1.sprite_index=0;
	player1.location.y=15;
	player1.location.x=30;

	Character_List.Character[1] = &enemy1;
	Character_List.number_of_characters++;	
	enemy1.sprite_index=4;
	enemy1.location.y=54;
	enemy1.location.x=54;

	Character_List.Character[2] = &enemy2;
	Character_List.number_of_characters++;
	enemy2.sprite_index=8;
	enemy2.location.y=34;
	enemy2.location.x=34;


	


	
	while(1)//main game loop**********************************************************************************************************************************
		{
		
		
				
		WaitVsync(1); //!!!!!!!!!The following input section was before vsych!!!!!!!!!!!!!!!!!!!!!!!
		int buttons = ReadJoypad(0); // get the button state for controller 1 (logical 0)
		if(buttons & BTN_UP && !player1.locked ){player1.intent.y=-1;player1.action=WALKING;player1.speed=1;}  
		else if(buttons & BTN_DOWN && !player1.locked ){player1.intent.y=1;player1.action=WALKING;player1.speed=1;}
		else if(!player1.locked) {player1.intent.y=0;player1.action=STANDING;}

		if(buttons & BTN_RIGHT && !player1.locked ){player1.intent.x=1;player1.facing=1;player1.action=WALKING;player1.speed=1;}
		else if(buttons & BTN_LEFT && !player1.locked ){player1.intent.x=-1;player1.facing=0;player1.action=WALKING;player1.speed=1;}
		else if(!player1.locked){player1.intent.x=0;player1.action=STANDING;}

		if(buttons & BTN_A)player1.action=KICK;
		if(buttons & BTN_B && !(player1.origin.z>0)){player1.velocity.z=11;}
		if(buttons & BTN_Y)player1.action=QUICK_PUNCH;
		if(buttons & BTN_X)player1.action=MEDIUM_PUNCH;

		if(buttons & BTN_SR);
		if(buttons & BTN_SL){player1.speed=2;player1.action=RUNNING;}

		if(buttons & BTN_START);
		if(buttons & BTN_SELECT);

		//enemy1.intent.x=1;

		handle_character_states(&player1);
		handle_character_states(&enemy1);
		handle_character_states(&enemy2);

		handle_ai(&Character_List);
		
		handle_collisions(&Character_List);

		handle_character_velocity(&player1);
		handle_character_velocity(&enemy1);
		handle_character_velocity(&enemy2);
		
		animate_character(&player1);
		animate_character(&enemy1);
		animate_character(&enemy2);
		
		map_character(&player1);
		map_character(&enemy1);
		map_character(&enemy2);

		//player1.debug = player1.animation[player1.action].current_frame;

		
		PrintByte(10,0,Character_List.Character[0]->life/*player1.life*/,false);
		PrintByte(23,0,score,false);
		//PrintByte(0,1,player1.debug,false);
		

		// NINJA STUFFS!
		MoveSprite(0,player1.location.x,player1.location.y-player1.origin.z,2,2); //adjusts the positions of sprites 3 to 6
		MoveSprite(4,enemy1.location.x,enemy1.location.y-enemy1.origin.z,2,2); //adjusts the positions of sprites 3 to 6
		MoveSprite(8,enemy2.location.x,enemy2.location.y-enemy1.origin.z,2,2); //adjusts the positions of sprites 3 to 6
		//MoveSprite(12,96,64,1,2); //adjusts the positions of sprites 3 to 6
			
		}// END MAIN GAME LOOP ******************************************************************************************************************************

} 
